package Group9.TodoManager.Data;

import java.util.List;

import javax.swing.ListModel;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

/**
 * SimpleListModel is used as the list model to be represented in the 
 * pop up List. It keeps Task objects.
 * @author volkan cambazoglu
 *
 */
public class SimpleListModel implements ListModel {
	
	private List<Object> list;	
	private int selectedRowIndex;
	private EventListenerList listenerlist;

	/**
	 * Constructor. Creates an instance of the list model
	 * @param listOfElements the task objects to be kept in the list model
	 */
	public SimpleListModel(List<Object> listOfElements) {
		super();
		list = listOfElements;
		listenerlist = new EventListenerList();
	}

    /**
     * Returns the selected index of the row in the list
     * @return selectedRowIndex
     */
    public int getSelectedRowIndex() {
        return selectedRowIndex;
    }

    /**
     * This is the setter method for selecting a row
     * @param selectedRowIndex
     */
    public void setSelectedRowIndex(int selectedRowIndex) {
        if(this.selectedRowIndex != selectedRowIndex){
            this.selectedRowIndex = selectedRowIndex;
        }
    }

    /**
     * Adds data listener to the list model
     * @param l list data listener
     */
	@Override
	public void addListDataListener(ListDataListener l) {
		listenerlist.add(ListDataListener.class, l);
	}

	/**
	 * Gets the element at the specified index
	 * @param index index of the element
	 * @return object task object
	 */
	@Override
	public Object getElementAt(int index) {
		return list.get(index);
	}
	
	/**
	 * Set the element in the list model
	 * Used basically for editing a task object
	 * @param index index of the element in the list
	 * @param element element to be placed at the specified index 
	 */
	public void setElement(int index, Object element){
		list.set(index, element);
	}
	
	/**
	 * It is used to get the index of an element in the list.
	 * @param element the element that is looked for
	 * @return index index of the element, -1 if it does not exist in the list
	 */
	public int indexOf(Object element){
		return list.indexOf(element);
	}

	/**
	 * Getter method of the size of the list.
	 * @return size number of elements in the list
	 */
	@Override
	public int getSize() {
		return list.size();
	}

	/**
	 * Removes data listener from the list model
	 * @param l the listener to be removed
	 */
	@Override
	public void removeListDataListener(ListDataListener l) {
		listenerlist.remove(ListDataListener.class, l);
	}
	
	/**
	 * Adds element to the list model
	 * @param item item to be added to the list
	 */
	public void addElement(Object item){
		list.add(item);
	}

	/**
	 * Removes element that is at the specified index from the list
	 * @param index index of the element
	 */
	public void removeElementAt(int index){
		if(index < list.size()){
			list.remove(index);
		}
	}
	
	/**
	 * Removes the element from the list
	 * @param item element to be removed from the list
	 */
	public void removeElement(Object item){
		list.remove(item);
	}
	
	/**
	 * Fires event when an interval is removed from the list model
	 * When this method is performed, all the attached listeners are
	 * notified of the removal.
	 * @param source source of the event
	 * @param index0 beginning index of the interval
	 * @param index1 end index of the interval
	 */
	protected void fireIntervalRemoved(Object source, int index0, int index1){
		Object [] listeners = listenerlist.getListenerList();
		for (int i = 0; i < listeners.length; i++) {
	         if (listeners[i]==ListDataListener.class) {
	             ListDataEvent listDataEvent = new ListDataEvent(this, 
	            		 ListDataEvent.INTERVAL_REMOVED, index0, index1);
	             ((ListDataListener)listeners[i]).intervalRemoved(listDataEvent);
	         }
		}
	}
	
	/**
	 * Creates a copy of the list model
	 * @return simpleListModel new copy
	 */
	public SimpleListModel copyModel(){
		try {
			return (SimpleListModel) clone();
		} catch (CloneNotSupportedException e) {
			System.err.println("Cannot copy list model!");
		}
		
		return null;
	}

	/**
	 * Clones the list model
	 * @return clone clone of the list model
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return new SimpleListModel(this.list.subList(0, this.list.size()));
	}
}
